package com.victor.core.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日期工具类
 */
public class DateUtil {


    /**
     * 获取YYYY格式
     *
     * @return
     */
    public static String getYear() {
        return formatDate(new Date(), "yyyy");
    }

    /**
     * 获取YYYY格式
     *
     * @return
     */
    public static String getYear(Date date) {
        return formatDate(date, "yyyy");
    }

    /**
     * 获取YYYY-MM格式
     *
     * @return
     */
    public static String getYearMonth() {
        return formatDate(new Date(), "yyyy-MM");
    }

    /**
     * 获取YYYY-MM格式
     *
     * @return
     */
    public static String getYearMonth(Date date) {
        return formatDate(date, "yyyy-MM");
    }


    /**
     * 获取YYYY-MM-DD格式
     *
     * @return
     */
    public static String getDay() {
        return formatDate(new Date(), "yyyy-MM-dd");
    }

    /**
     * 获取YYYY-MM-DD格式
     *
     * @return
     */
    public static String getDay(Date date) {
        return formatDate(date, "yyyy-MM-dd");
    }

    /**
     * 获取YYYYMMDD格式
     *
     * @return
     */
    public static String getDays() {
        return formatDate(new Date(), "yyyyMMdd");
    }

    /**
     * 获取YYYYMMDD格式
     *
     * @return
     */
    public static String getDays(Date date) {
        return formatDate(date, "yyyyMMdd");
    }

    /**
     * 获取YYYY-MM-DD HH:mm:ss格式
     *
     * @return
     */
    public static String getTime() {
        return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 获取YYYY-MM-DD HH:mm:ss.SSS格式
     *
     * @return
     */
    public static String getMsTime() {
        return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss.SSS");
    }

    /**
     * 获取YYYYMMDDHHmmss格式
     *
     * @return
     */
    public static String getAllTime() {
        return formatDate(new Date(), "yyyyMMddHHmmss");
    }

    /**
     * 获取YYYY-MM-DD HH:mm:ss格式
     *
     * @return
     */
    public static String getTime(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    public static String formatDate(Date date, String pattern) {
        String formatDate = null;
        if (StringUtils.isNotBlank(pattern)) {
            formatDate = DateFormatUtils.format(date, pattern);
        } else {
            formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
        }
        return formatDate;
    }

    /**
     * @param s
     * @param e
     * @return boolean
     * @throws
     * @Title: compareDate
     * @Description:(日期比较，如果s>=e 返回true 否则返回false)
     * @author luguosui
     */
    public static boolean compareDate(String s, String e) {
        if (parseDate(s) == null || parseDate(e) == null) {
            return false;
        }
        return parseDate(s).getTime() >= parseDate(e).getTime();
    }

    /**
     * 格式化日期
     *
     * @return
     */
    public static Date parseDate(String date) {
        return parse(date, "yyyy-MM-dd");
    }

    /**
     * 格式化日期
     *
     * @return
     */
    public static Date parseTime(String date) {
        return parse(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 格式化日期
     *
     * @return
     */
    public static Date parse(String date, String pattern) {
        try {
            return DateUtils.parseDate(date, pattern);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 格式化日期
     *
     * @return
     */
    public static String format(Date date, String pattern) {
        return DateFormatUtils.format(date, pattern);
    }

    /**
     * 把日期转换为Timestamp
     *
     * @param date
     * @return
     */
    public static Timestamp format(Date date) {
        return new Timestamp(date.getTime());
    }

    /**
     * 校验日期是否合法
     *
     * @return
     */
    public static boolean isValidDate(String s) {
        return parse(s, "yyyy-MM-dd HH:mm:ss") != null;
    }

    /**
     * 校验日期是否合法
     *
     * @return
     */
    public static boolean isValidDate(String s, String pattern) {
        return parse(s, pattern) != null;
    }

    public static int getDiffYear(String startTime, String endTime) {
        DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        try {
            int years = (int) (((fmt.parse(endTime).getTime() - fmt.parse(
                    startTime).getTime()) / (1000 * 60 * 60 * 24)) / 365);
            return years;
        } catch (Exception e) {
            // 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
            return 0;
        }
    }

    /**
     * <li>功能描述：时间相减得到天数
     *
     * @param beginDateStr
     * @param endDateStr
     * @return long
     * @author Administrator
     */
    public static long getDaySub(String beginDateStr, String endDateStr) {
        long day = 0;
        SimpleDateFormat format = new SimpleDateFormat(
                "yyyy-MM-dd");
        Date beginDate = null;
        Date endDate = null;

        try {
            beginDate = format.parse(beginDateStr);
            endDate = format.parse(endDateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        day = (endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000);
        // System.out.println("相隔的天数="+day);

        return day;
    }

    /**
     * 得到n天之后的日期
     *
     * @param days
     * @return
     */
    public static String getAfterDayDate(String days) {
        int daysInt = Integer.parseInt(days);
        /**
         * java.util包
         */
        Calendar canlendar = Calendar.getInstance();
        /**
         * 日期减 如果不够减会将月变动
         */
        canlendar.add(Calendar.DATE, daysInt);
        Date date = canlendar.getTime();

        SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = sdfd.format(date);

        return dateStr;
    }

    /**
     * 得到n天之后是周几
     *
     * @param days
     * @return
     */
    public static String getAfterDayWeek(String days) {
        int daysInt = Integer.parseInt(days);
        /**
         * java.util包
         */
        Calendar canlendar = Calendar.getInstance();
        /**
         * 日期减 如果不够减会将月变动
         */
        canlendar.add(Calendar.DATE, daysInt);
        Date date = canlendar.getTime();

        SimpleDateFormat sdf = new SimpleDateFormat("E");
        String dateStr = sdf.format(date);

        return dateStr;
    }

    /**
     * 获取某年某月的天数
     *
     * @param year
     * @param month
     * @return
     */
    public static int getDayOfMonth(int year, int month) {
        Calendar time = Calendar.getInstance();
        time.clear();
        time.set(Calendar.YEAR, year);
        /**
         * Calendar对象默认一月为0
         */
        time.set(Calendar.MONTH, month);
        /**
         * 本月份的天数
         */
        int maxday = time.getActualMaximum(Calendar.DAY_OF_MONTH);
        return maxday;
    }

    public static void main(String[] args) {
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        System.out.println(c.getActualMaximum(Calendar.DAY_OF_MONTH));
        c.set(Calendar.DAY_OF_MONTH, 1);
        //Integer[] days = {7,1,2,3,4,5,6};
        // c.setTime(parse("2018-04-15","yyyy-MM-dd"));
        int w = c.get(Calendar.DAY_OF_WEEK) - 1;
        System.out.println(w);
    }

    /**
     * 获取某年某月的天数
     */
    public static List<String> getDaysWithMonth(String yyyy, String mm) {
        int max = DateUtil.getDayOfMonth(Integer.valueOf(yyyy), Integer.valueOf(mm) - 1);
        int day = getNowDay();
        List<String> list = new ArrayList<>();
        for (int i = 1; i <= max; i++) {
            if (i <= day) {
                if (i < 10) {
                    list.add("0" + String.valueOf(i));
                } else {
                    list.add(String.valueOf(i));
                }
            }
        }
        return list;
    }

    /**
     * <b>Description:获取当前天</b><br>
     *
     * @return
     * @Note <b>Author:</b>zhaojiabin</a>
     * <br><b>Date:</b> 2017年10月30日 下午3:00:41
     * <br><b>Version:</b> 1.0
     */
    public static int getNowDay() {
        SimpleDateFormat format = new SimpleDateFormat("dd");
        return Integer.valueOf(format.format(new Date()));
    }

    /**
     * @Auther:Victor
     * @Description:获取当前时间为周几
     * @Date:Create in 14:54 2018/4/11
     * @Modified By:
     */
    public static int getNowWeek() {
        Integer[] days = {7, 1, 2, 3, 4, 5, 6};
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        int w = c.get(Calendar.DAY_OF_WEEK) - 1;
        return days[w];
    }

    public static int getWeek(String str) {
        Integer[] days = {7, 1, 2, 3, 4, 5, 6};
        Calendar c = Calendar.getInstance();
        c.setTime(parse(str, "yyyy-MM-dd"));
        int w = c.get(Calendar.DAY_OF_WEEK) - 1;
        return days[w];
    }

    /**
     * <b>Description:获取当前小时</b><br>
     *
     * @return
     * @Note <b>Author:</b>zhaojiabin</a>
     * <br><b>Date:</b> 2017年10月30日 下午3:00:41
     * <br><b>Version:</b> 1.0
     */
    public static int getNowHour() {
        SimpleDateFormat format = new SimpleDateFormat("HH");
        return Integer.valueOf(format.format(new Date()));
    }

    /**
     * 获取一天的小时数
     */
    public static List<String> getHours() {
        //int year = ca.get(Calendar.YEAR);//获取年份
        //int month=ca.get(Calendar.MONTH);//获取月份
        //int day=ca.get(Calendar.DATE);//获取日
        //int hour=ca.get(Calendar.HOUR);//小时
        //int minute=ca.get(Calendar.MINUTE);//分
        //int second=ca.get(Calendar.SECOND);//秒
        //int WeekOfYear = ca.get(Calendar.DAY_OF_WEEK); //星期
        int hour = getNowHour();
        List<String> list = new ArrayList<>();
        for (int i = 0; i < 24; i++) {
            if (i <= hour) {
                if (i < 10) {
                    list.add("0" + String.valueOf(i));
                } else {
                    list.add(String.valueOf(i));
                }
            }
        }
        return list;
    }

    /**
     * 获取两个日期之间的所有日期
     */
    public static List<String> getBetweenDates(String start, String end, String format) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        List<String> result = new ArrayList<String>();
        Calendar tempStart = Calendar.getInstance();
        tempStart.setTime(sdf.parse(start));
        //tempStart.add(Calendar.DAY_OF_YEAR, 1);

        Calendar tempEnd = Calendar.getInstance();
        tempEnd.setTime(sdf.parse(end));
        tempEnd.add(Calendar.DAY_OF_YEAR, 1);
        while (tempStart.before(tempEnd)) {
            result.add(sdf.format(tempStart.getTime()));
            tempStart.add(Calendar.DAY_OF_YEAR, 1);
        }
        return result;
    }

    /**
     * 获取当前周的起止日期
     *
     * @return
     */
    public static Map<String, String> getFirstAndLastWithWeek(String format) {
        Map<String, String> map = new HashMap<>(2);
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        int d = 0;
        if (cal.get(Calendar.DAY_OF_WEEK) == 1) {
            d = -6;
        } else {
            d = 2 - cal.get(Calendar.DAY_OF_WEEK);
        }
        cal.add(Calendar.DAY_OF_WEEK, d);
        //所在周开始日期
        map.put("starttime", sdf.format(cal.getTime()));
        cal.add(Calendar.DAY_OF_WEEK, 6);
        //所在周结束日期
        map.put("endtime", sdf.format(cal.getTime()));
        return map;
    }

    /**
     * 获取当前周的起止日期
     *
     * @return
     */
    public static Map<String, String> getCustomDefault(String format) {
        Map<String, String> map = new HashMap<>(2);
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        //结束日期 当前日期
        map.put("endtime", sdf.format(cal.getTime()));
        cal.add(Calendar.DAY_OF_WEEK, -7);
        //开始日期 -7天
        map.put("starttime", sdf.format(cal.getTime()));
        return map;
    }

    private final static int ONE_DAY_SEC = 60 * 60 * 24;
    private final static int ONE_HOUR_SEC = 60 * 60;

    /**
     * @Auther:Victor
     * @Description:根据毫秒 格式化时间
     * @Date:Create in 17:34 2018/5/3
     * @Modified By:
     */
    public static String formatMsec(long msec) {

        long sec = msec / 1000;
        int d = (int) sec / ONE_DAY_SEC;//天
        sec -= (d * ONE_DAY_SEC);
        int h = (int) sec / ONE_HOUR_SEC;//小时
        sec -= (h * ONE_HOUR_SEC);
        int m = (int) sec / 60;//分钟
        sec -= (m * 60);
        int s = (int) sec;
        StringBuffer sb = new StringBuffer("");
        if (d > 0) {
            sb.append(d).append("天");
        }
        if (h > 0) {
            sb.append(h).append("小时");
        }
        if (m > 0) {
            sb.append(m).append("分钟");
        }
        if (s > 0) {
            sb.append(s).append("秒");
        }
        return sb.toString();
    }
    /**
     * 格式化Oracle Date
     *
     * @param value
     * @return
     */
//	public static String buildDateValue(Object value){
//		if(Func.isOracle()){
//			return "to_date('"+ value +"','yyyy-mm-dd HH24:MI:SS')";
//		}else{
//			return Func.toStr(value);
//		}
//	}
    /**
     * @Auther:Victor
     * @Description: 获取 +n 天后的日期
     * @Date:Create in 18:17 2018/5/28
     * @Modified By:
     */
    public static Date addAndSubtractDaysByCalendar(Date dateTime/*待处理的日期*/,int n/*加减天数*/) {

        java.util.Calendar calstart = java.util.Calendar.getInstance();
        calstart.setTime(dateTime);
        calstart.add(java.util.Calendar.DAY_OF_WEEK, n);
        return calstart.getTime();
    }
    }
